home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
051-075
/
disk_068
/
mg1b
/
tty
/
amiga
/
ttyio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
24KB
|
986 lines
/*
* Name: MicroEmacs
* Amiga terminal-dependent I/O (Intuition)
* Last Edit: 12-Mar-87 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
* Created: 21-Apr-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
*/
/*
* Lots of includes.
*/
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/tasks.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <devices/console.h>
#include <libraries/dos.h>
#include <graphics/clip.h>
#include <graphics/view.h>
#include <graphics/rastport.h>
#include <graphics/layers.h>
#include <graphics/text.h>
#include <graphics/gfxbase.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#ifdef CHANGE_FONT
#include <libraries/diskfont.h>
#endif
#undef TRUE /* avoid redefinition messages */
#undef FALSE
#include "def.h" /* includes sysdef.h and ttydef.h */
/*
* External Amiga functions. Declared explicitly
* to avoid problems with different compilers.
*/
extern LONG AbortIO();
extern LONG CloseDevice();
extern LONG CloseLibrary();
extern LONG CloseWindow();
extern struct MsgPort *CreatePort();
extern struct IOStdReq *CreateStdIO();
extern LONG DeletePort();
extern LONG DeleteStdIO();
extern struct IntuiMessage *GetMsg();
extern int OpenConsole();
extern char *OpenLibrary();
extern struct Window *OpenWindow();
#ifdef CHANGE_FONT
extern struct TextFont *OpenDiskFont();
#endif
extern LONG RectFill();
extern LONG ReplyMsg();
extern LONG SetAPen();
extern LONG SetDrMd();
extern LONG Wait();
#ifdef DO_MENU
extern LONG ClearMenuStrip(); /* menu functions */
extern struct Menu *InitEmacsMenu();
extern struct MenuItem *ItemAddress();
extern LONG SetMenuStrip();
#endif
#ifdef MANX
extern int Enable_Abort; /* Do NOT allow abort! */
#endif
#ifdef LATTICE
/*
* Internal functions that LATTICE wants to be void. Declare here to
* avoid redeclaration errors.
*/
VOID ttclose() ;
VOID ttputc(unsigned char) ;
VOID ttflush() ;
VOID setttysize() ;
VOID panic(char *) ;
static VOID remevt() ;
static VOID qchar(unsigned char) ;
#ifdef MOUSE
static VOID qmouse(SHORT, SHORT, USHORT) ;
#endif
#ifdef DO_MENU
static VOID qmenu(USHORT) ;
#endif
#else
/*
* Internal functions for Manx, to avoid redeclaration errors.
*/
VOID ttclose(), ttputc(), ttflush(), setttysize(), panic();
static VOID remevt(), qchar();
#ifdef MOUSE
static VOID qmouse();
#endif
#ifdef DO_MENU
static VOID qmenu();
#endif
#endif LATTICE
/*
* External MicroEmacs functions and variables
*/
extern int quit(); /* Defined by "main.c" */
extern char *version; /* Version information */
/*
* Library bases (used by glue libraries)
*/
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
#ifdef CHANGE_FONT
ULONG DiskfontBase;
#endif
/*
* Intuition window and menu variables
*/
#define WINDOWGADGETS (WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE)
static short borderless = TRUE; /* Flag for borderless window */
static short leftedge = 0, /* Last top left position */
topedge = 0;
static short width, height; /* Set by ttopen() */
struct NewWindow MicroEMACS = {
0, 0, /* start position */
0, 0, /* width, height (set by ttopen)*/
0, 1, /* detail pen, block pen */
#ifdef DO_MENU
MENUPICK | /* If menu is used */
#endif
#ifdef MOUSE
MOUSEBUTTONS | /* If mouse is used */
#endif
INTUITICKS |
CLOSEWINDOW | NEWSIZE, /* IDCMP flags */
0, /* window flags (set by ttopen) */
NULL, /* pointer to first user gadget */
NULL, /* pointer to user checkmark */
NULL, /* title (filled in later) */
NULL, /* pointer to screen (none) */
NULL, /* pointer to superbitmap */
359,101, /* minimum size (with TOPAZ_80) */
0, 0, /* maximum size (set by ttopen) */
WBENCHSCREEN /* screen in which to open */
};
struct Window *EmW; /* Our window */
static short toggling = FALSE; /* Prevent menu wiping */
#ifdef DO_MENU
static struct Menu *EmacsMenu = NULL; /* Our menu */
#endif
#ifdef CHANGE_FONT
static struct TextFont *EmFont = NULL;
#endif
/*
* The bridge between Intuition events and Emacs' single
* input stream...
*/
static ULONG class; /* Intuition event */
static USHORT code, /* information */
qualifier;
static APTR address;
static SHORT x, y;
static LONG intuitionMsgBit; /* Signal bit */
#define INTUITION_MESSAGE ((LONG) (1L << intuitionMsgBit))
/*
* To more thoroughly handle Intuition events, we buffer
* them into a circular queue until other routines ask
* for the information carried in them.
*/
#define NIBUF 256 /* Rather roomy... */
#define EVT_KBD 0
#define EVT_MOUSE 1
#define EVT_MENU 2
#define NULLEVT ((struct event *) 0)
struct event {
USHORT type; /* What is it? */
union {
UBYTE ch; /* Keyboard event */
struct { /* Mouse click */
SHORT row, col; /* location in character raster */
USHORT qualifier;
} mouse;
USHORT code; /* Menu event */
} data;
} ibuf[NIBUF]; /* Input buffer */
int ibufo, nibuf; /* head, # of bytes in ibuf */
/*
* Console output
*/
#define CSI 0x9b /* Command Sequence Introducer */
#define ESC 0x1b /* Escape key */
#define NOBUF 512 /* About 1/4 screen */
static struct MsgPort *consoleWritePort; /* I/O ports */
static struct MsgPort *consoleReadPort;
static struct IOStdReq *consoleWriteMsg; /* I/O messages */
static struct IOStdReq *consoleReadMsg;
static LONG consoleMsgBit; /* signal bit */
#define CONSOLE_MESSAGE ((LONG) (1L << consoleMsgBit))
static unsigned char letter; /* Console input buffer */
static unsigned char obuf[NOBUF]; /* Terminal output buffer */
int nobuf; /* # of bytes in above */
int nrow; /* Terminal size, rows. */
int ncol; /* Terminal size, columns. */
extern int ttrow; /* Current cursor row */
#define PROMPTWAIT 20 /* ticks to wait before timeout */
static LONG tickcount; /* # intuiticks since last char */
/*
* Open up the virtual terminal MicroEMACS communicates with.
* Set up the window, console, and menu strip.
*/
ttopen()
{
register struct Screen *s;
#ifdef MANX
Enable_Abort = 0; /* Disable ^C */
#endif
GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library", (LONG) 0);
if (GfxBase == NULL) /* Graphics lib */
cleanup(1);
IntuitionBase = (struct IntuitionBase *) /* Intuition */
OpenLibrary("intuition.library", (LONG) 0);
if (IntuitionBase == NULL)
cleanup(2);
#ifdef CHANGE_FONT
DiskfontBase = (ULONG) OpenLibrary("diskfont.library", (LONG)0);
if (DiskfontBase == NULL)
cleanup(21);
#endif
/*
* Create our window. Set window flags based on the current
* value of the borderless flag, and the maximum size of the
* window based on the size of the first screen in the screen
* list with screen type WBENCHSCREEN (of which there had better
* be *EXACTLY* one, right???...). To avoid possible crashes
* if user is moving screens around, turn off multitasking
* during the loop.
*/
Forbid(); /* user might be moving screen */
for (s = IntuitionBase->FirstScreen; s ; s = s->NextScreen)
if ((s->Flags & SCREENTYPE) == WBENCHSCREEN)
break;
width = MicroEMACS.MaxWidth = s->Width;
height = MicroEMACS.MaxHeight = s->Height;
Permit();
/* Set the window size based on the last one that was open,
* if it was borderless. Otherwise make it fill the screen.
* Set max/min widths based on current screen size.
*
* Set flags and window title, then open window
*/
if (borderless) {
MicroEMACS.Flags = WINDOWGADGETS | ACTIVATE | BORDERLESS;
#ifdef TOGGLE_ZOOMS
MicroEMACS.LeftEdge = 0;
MicroEMACS.TopEdge = 0;
MicroEMACS.Width = MicroEMACS.MaxWidth;
MicroEMACS.Height = MicroEMACS.MaxHeight;
#endif
} else {
MicroEMACS.Flags = WINDOWGADGETS | ACTIVATE | WINDOWSIZING;
#ifndef TOGGLE_ZOOMS
}
#endif
MicroEMACS.LeftEdge = leftedge;
MicroEMACS.TopEdge = topedge;
MicroEMACS.Width = width;
MicroEMACS.Height = height;
#ifdef TOGGLE_ZOOMS
}
#endif
MicroEMACS.Title = (UBYTE *) version; /* name for window */
if ((EmW = OpenWindow(&MicroEMACS)) == NULL)
cleanup(3);
#ifdef CHANGE_FONT
/* If the user requested a different font for the text, EmFont
* will be non-null, so set the font for the RastPort. The
* conole device will pick this up when we open it later on.
*/
if (EmFont)
SetFont(EmW->RPort, EmFont);
#endif
/* Once the window is created, get the Intuition signal bit,
* set up the menu, and tell the virtual terminal how big
* it is.
*/
intuitionMsgBit = EmW->UserPort->mp_SigBit;
#ifdef DO_MENU
if (toggling == FALSE)
EmacsMenu = InitEmacsMenu(EmW);
SetMenuStrip(EmW, EmacsMenu);
#endif
setttysize();
/* Set up the console device. Create the necessary read/write
* ports and messages, attach the console device thus created
* to our window, initialize the console input buffer, and
* queue the first read to the console.
*/
consoleWritePort = CreatePort("Emacs.con.write",(LONG) 0);
if (consoleWritePort == NULL)
cleanup(4);
consoleWriteMsg = CreateStdIO(consoleWritePort);
if (consoleWriteMsg == NULL)
cleanup(5);
consoleReadPort = CreatePort("Emacs.con.read",(LONG) 0);
if (consoleReadPort == NULL)
cleanup(6);
consoleReadMsg = CreateStdIO(consoleReadPort);
if (consoleReadMsg == NULL)
cleanup(7);
if (OpenConsole(consoleWriteMsg,consoleReadMsg,EmW) != 0)
cleanup(8);
consoleMsgBit = consoleReadPort->mp_SigBit;
QueueRead(consoleReadMsg,&letter);
nibuf = ibufo = 0;
return (0);
}
/*
* Close the virtual terminal, aborting any
* I/O to the console device and de-allocating
* everything we have allocated.
*/
VOID
ttclose()
{
ttflush();
AbortIO(consoleReadMsg);
CloseDevice(consoleWriteMsg);
cleanup(0);
#ifdef MANX
Enable_Abort = 1;
#endif
}
/*
* Toggle between a borderless window
* and a sizeable window. This lets you
* use the whole screen if you want.
* Bound to "toggle-window-hack" by
* ttykbd.c
*/
togglewindow(f, n, k)
{
toggling = TRUE; /* Notify the system */
#ifdef TOGGLE_ZOOMS
if (!borderless) {
#endif
leftedge = EmW->LeftEdge; /* save window state */
topedge = EmW->TopEdge;
width = EmW->Width;
height = EmW->Height;
#ifdef TOGGLE_ZOOMS
}
#endif
ttclose(); /* reset to zero */
borderless = !borderless; /* toggle window flag */
ttopen(); /* re-open tty window */
ttinit(); /* re-initalize tty */
sgarbf = TRUE; /* screen was trashed */
nrow = ncol = -1; /* trash screen size */
refresh(); /* and redraw it */
toggling = FALSE; /* Ok, done */
return (TRUE);
}
#ifdef CHANGE_FONT
/*
* Select a different font for the Emacs window.
* This obviously does not work very well
* with proportional fonts, so we ask the
* user to confirm before he uses one.
* It's available if you want to be able
* to use your own disk font (or Topaz 11
* under 1.2) to edit with.
*/
setfont(f, n, k)
{
register int s, size;
register struct TextFont *newfont;
char fontname[80], fontpath[84], fontsize[3];
struct TextAttr ta;
/* Get font size */
if (f == TRUE)
size = n;
else {
if ((s = ereply("Font size: ",
fontsize, sizeof(fontsize))) != TRUE)
return (s);
size = atoi(fontsize);
}
if (size <= 0) { /* reset to default font */
if (EmFont)
CloseFont(EmFont);
EmFont = NULL;
} else { /* user wants to set a new font name */
if ((s = ereply("Font name: ",
fontname, sizeof(fontname))) != TRUE)
return (s);
strcpy(fontpath,fontname);
strncat(fontpath,".font",sizeof(fontpath));/* make name */
/* set up text attributes */
ta.ta_Name = (UBYTE *)fontpath;
ta.ta_YSize = size;
ta.ta_Style = FS_NORMAL;
ta.ta_Flags = 0; /* use either */
/* Look for the font */
ewprintf("Looking for %s %d...",fontname,size);
if ((newfont = OpenDiskFont(&ta)) == NULL) {
ewprintf("Can't find %s %d!",fontname,size);
return (FALSE);
} else { /* Found it! Check before using it. */
if ((newfont->tf_YSize != size) && ((s = eyesno(
"Size unavailable - use closest"))!=TRUE)){
CloseFont(newfont);
return (FALSE);
}
if ((newfont->tf_Flags & FPF_PROPORTIONAL) &&
(((s = eyesno("Use proportional font")))!=TRUE)){
CloseFont(newfont);
return (FALSE);
}
/* Get rid of old font and cache the new one */
if (EmFont)
CloseFont(EmFont);
EmFont = newfont;
}
}
/* Now that the font is selected, close the window. */
toggling = TRUE; /* Notify the system */
ttclose(); /* reset to zero */
ttopen(); /* re-open w/new font */
ttinit(); /* re-init console */
nrow = -1; /* trash size */
ncol = -1; /* so refresh() works */
refresh(); /* redo whole screen */
if (size > 0)
ewprintf("Now using font %s %d",fontname,EmFont->tf_YSize);
else
ewprintf("Now using default font");
return (TRUE);
}
#endif
/*
* Write a single character to the screen.
* Buffered for extra speed, so ttflush()
* does all the work.
*/
VOID
ttputc(c)
unsigned char c;
{
obuf[nobuf++] = c;
if (nobuf >= NOBUF)
ttflush();
}
/*
* Flush characters from the output buffer.
* Just blast it out with a console write call.
*/
VOID
ttflush()
{
if (nobuf > 0) {
ConWrite(consoleWriteMsg, obuf, nobuf);
nobuf = 0;
}
}
/*
* Get a character for Emacs, without echo or
* translation.
*/
ttgetc()
{
return handle_kbd(FALSE); /* wait for char w/o timeout */
}
/*
* Return TRUE if we've waited for 2 seconds and nothing has
* happened, else return false.
*/
ttwait()
{
return handle_kbd(TRUE); /* time out after 2 sec */
}
/*
* Common routine for handling character input, with and
* without timeout. Handle events until:
*
* 1) a character is put in the input buffer
* 2) if timeout == TRUE, PROMPTWAIT IntuiTicks have gone by
*
* If timeout == FALSE, the character is returned and removed from
* the input buffer.
* If timeout == TRUE, returns TRUE if the read timed out, else FALSE.
* I.e. FALSE indicates a character was typed before the time limit
*/
static handle_kbd(timeout)
register int timeout;
{
register struct IntuiMessage *message; /* IDCMP message */
register LONG wakeupmask; /* which signals? */
register int charfound; /* got a character yet? */
unsigned char nextchar(); /* return next char evt */
tickcount = 0; /* always zero the count */
if (striptochar()) /* any chars in buffer? */
return timeout ? FALSE : ((int) (nextchar() & 0xFF));
charfound = FALSE; /* nope -- have to wait */
do {
wakeupmask = Wait(INTUITION_MESSAGE|CONSOLE_MESSAGE);
if (wakeupmask & CONSOLE_MESSAGE) { /* keyboard */
GetMsg(consoleReadPort); /* free message */
qchar(letter); /* do this FIRST */
QueueRead(consoleReadMsg, &letter);
charfound = TRUE;
}
/* Intuition event. Handle Intuiticks specially. */
if (wakeupmask & INTUITION_MESSAGE)
while(message = GetMsg(EmW->UserPort))
if (message->Class == INTUITICKS) {
tickcount++;
ReplyMsg(message);
} else if (dispatch(message) == TRUE)
charfound = TRUE;
/* time out if enough ticks have gone by without
* any keyboard input. We do this *after* all the
* events in the current list have been dispatched.
*/
if (timeout && (tickcount > PROMPTWAIT))
break;
} while (charfound == FALSE);
/* If called by ttwait(), return FALSE if a character was found.
* Else return the next character in the input buffer
*/
return timeout ? (!charfound) : ((int) (nextchar() & 0xFF));
}
/*
* Handle the events we handle... The result
* returned indicates if we've put a character
* in the input buffer.
*/
static dispatch(msg)
register struct IntuiMessage *msg;
{
#ifdef DO_MENU
register struct MenuItem *item;
#endif
register int txheight, txwidth;
register struct RastPort *rp;
int dx, dy, fgpen, drmode;
class = msg->Class; /* grab the info before we */
code = msg->Code; /* reply to the message */
qualifier = msg->Qualifier;
address = msg->IAddress;
x = msg->MouseX;
y = msg->MouseY;
ReplyMsg(msg); /* return it to Intuition */
switch(class) { /* see what the fuss is about */
#ifdef DO_MENU
case MENUPICK:
if (code == MENUNULL)
return (FALSE);
while (code != MENUNULL) {/* handle multiple selection */
qmenu(code);
item = ItemAddress(EmacsMenu,(LONG) code);
code = item->NextSelect;
}
return (TRUE); /* puts <CSI>M~ in event queue */
break;
#endif
#ifdef MOUSE
case MOUSEBUTTONS: /* fake the mouse key */
if (code != SELECTDOWN) /* ignore SELECTUP */
return (FALSE);
qmouse(x, y, qualifier);
return (TRUE);
break;
#endif
case NEWSIZE:
/* Sometimes when you resize the window to make it
* smaller, garbage is left at the right and bottom
* sides of the window. This code is devoted to
* (somehow) getting rid of this garbage. Any
* suggestions?
*/
rp = EmW->RPort;
fgpen = rp->FgPen; /* save params */
drmode = rp->DrawMode;
SetDrMd(rp, (LONG) JAM1);
SetAPen(rp, (LONG) EmW->RPort->BgPen);
/* Check the bottom of the window
*/
txheight = EmW->Height - EmW->BorderTop - EmW->BorderBottom;
if (dy = (txheight % FontHeight(EmW)))
RectFill(rp,
(LONG) EmW->BorderLeft,
(LONG) EmW->BorderTop + txheight - dy - 1,
(LONG) (EmW->Width - 1) - EmW->BorderRight,
(LONG) (EmW->Height - 1) - EmW->BorderBottom);
/* Check the right side
*/
txwidth = EmW->Width - EmW->BorderLeft - EmW->BorderRight;
if (dx = txwidth % FontWidth(EmW))
RectFill(rp,
(LONG) EmW->BorderLeft + txwidth - dx - 1,
(LONG) EmW->BorderTop,
(LONG) (EmW->Width - 1) - EmW->BorderRight,
(LONG) (EmW->Height - 1) - EmW->BorderBottom);
SetDrMd(rp, (LONG) drmode);
SetAPen(rp, (LONG) fgpen); /* restore colors */
/* Tell the console device to resize itself */
ttputc(CSI);
ttputc('t');
ttputc(CSI);
ttputc('u');
ttflush();
/* Signal the editor that a new size has occurred */
qchar(ESC);
qchar('\f');
return (TRUE); /* we done (finally) */
break;
case CLOSEWINDOW: /* Call quit() directly */
quit(FALSE, 1, KRANDOM);
return (FALSE);
break;
default:
panic("HandleMsg: unknown event!!!");
break;
}
return(FALSE);
}
#ifdef DO_MENU
/*
* Return the next menu selection number to
* the caller. Used by "ttymenu.c".
*/
ttmenu(codep)
USHORT *codep;
{
register struct event *e;
struct event *nextevt();
e = nextevt();
if (e->type != EVT_MENU)
return (FALSE);
*codep = e->data.code;
remevt(); /* remove event by hand */
return (TRUE);
}
#endif
#ifdef MOUSE
/*
* Return the next mouse click values to
* the caller. *Rowp and *colp will contain
* the row and column where the mouse click occured.
* This is so that only the terminal driver has
* to know about the size of the window's font.
* If the flag argument f is FALSE, the mouse event
* is *not* removed from the queue, allowing routines
* that need to (mainly getmouse()) to peek at it.
*/
ttmouse(f, rowp,colp,qualp)
int f;
USHORT *rowp, *colp, *qualp;
{
register struct event *e;
struct event *nextevt();
e = nextevt();
if (e->type != EVT_MOUSE)
return (FALSE); /* next isn't mouse evt */
*colp = e->data.mouse.col;
*rowp = e->data.mouse.row;
*qualp = e->data.mouse.qualifier;
if (f)
remevt(); /* remove the event */
return (TRUE);
}
#endif
/*
* Return the current size of the virtual
* terminal in nrow and ncol, making sure
* we don't go beyond the size of the internal
* video array.
* Assumes the current font is monospaced
* (not always safe bet any more :-) :-).
*/
VOID
setttysize()
{
nrow = (EmW->Height - TOP_OFFSET
- EmW->BorderBottom) / FontHeight(EmW);
ncol = (EmW->Width - EmW->BorderLeft
- EmW->BorderRight) / FontWidth(EmW);
if (nrow < 1)
nrow = 1;
if (nrow > NROW)
nrow = NROW;
if (ncol < 1)
ncol = 1;
if (ncol > NCOL)
ncol = NCOL;
}
/*
* Exit as soon as possible, after displaying
* the message.
*/
VOID
panic(s)
char *s;
{
ewprintf(s); /* put message at bottom */
Delay((ULONG) 90); /* wait 1.5 seconds */
ttclose(); /* get rid of window &resources */
exit(10000); /* go 'way */
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Event buffer management *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* If the buffer's full, crap out, else
* return a pointer to the (ibufo + nibuf)'th
* event record (mod NIBUF). Postincrement
* nibuf so it points at the next record and
* also keeps track of how many events
* are in the buffer.
*/
static struct event *newevt()
{
return ((nibuf < NIBUF) ?
(ibuf + ((ibufo + nibuf++) % NIBUF)) : NULLEVT);
}
/*
* Return pointer to next item in queue,
* *without* removing it.
*/
static struct event *nextevt()
{
return (nibuf ? (ibuf + ibufo) : NULLEVT);
}
/*
* Move buffer pointer to next item in queue.
*/
static VOID
remevt()
{
if (nibuf <= 0)
nibuf = 0;
else {
nibuf--;
ibufo++;
ibufo %= NIBUF; /* wrap around in buffer */
}
}
/*
* Return true if there are some characters available
* in the buffer. Unlike striptochar, don't do anything
* to the input buffer, just return a value.
*/
typeahead()
{
register int bufp;
for (bufp = 0; bufp < nibuf; bufp++)
if (ibuf[(ibufo + bufp) % NIBUF].type == EVT_KBD)
return (TRUE);
return (FALSE);
}
/*
* See if there are any characters queued,
* stripping any other events that may
* be in the way. *Don't* remove the character
* from the queue.
*/
static
striptochar()
{
register struct event *e;
while (e = nextevt())
if (e->type == EVT_KBD)
return (TRUE);
else
remevt();
return (FALSE);
}
/*
* Return next character in event buffer.
*/
static unsigned char
nextchar()
{
register struct event *e;
if (e = nextevt()) {
remevt();
return (e->data.ch);
}
else
return ((unsigned char) 0); /* shouldn't happen */
}
/*
* Add a keyboard event to the queue
*/
static VOID
qchar(c)
unsigned char c;
{
register struct event *e;
if (e = newevt()) {
e->type = EVT_KBD;
e->data.ch = c;
}
}
#ifdef MOUSE
/*
* Add a mouse event to the queue, calculating
* the row and column value from the current height
* and width of the window's font.
*/
static VOID
qmouse(x, y, qual)
SHORT x, y;
USHORT qual;
{
register struct event *e;
qchar(CSI);
qchar('P');
qchar('~');
if (e = newevt()) {
e->type = EVT_MOUSE;
e->data.mouse.col = (x - EmW->BorderLeft) / FontWidth(EmW);
e->data.mouse.row = (y - TOP_OFFSET) / FontHeight(EmW);
e->data.mouse.qualifier = qual;
}
}
#endif
#ifdef DO_MENU
/*
* Add a menu key to queue
*/
static VOID
qmenu(code)
USHORT code;
{
register struct event *e;
qchar(CSI); /* menu key sequence */
qchar('M');
qchar('~');
if (e = newevt()) {
e->type = EVT_MENU;
e->data.code = code;
}
}
#endif
/*
* Clean up.
*
* Fall through all the possible cases (0 means
* get rid of everything and start with the case
* that fits the error situation).
*/
static cleanup(prob)
{
switch (prob) {
case 0: /* just clean everything up
case 8: /* couldn't open console device */
DeleteStdIO(consoleReadMsg);
case 7: /* couldn't get console read msg */
DeletePort(consoleReadPort);
case 6: /* couldn't get console read port */
DeleteStdIO(consoleWriteMsg);
case 5: /* couldn't get console write msg */
DeletePort(consoleWritePort);
case 4: /* couldn't get console write port */
#ifdef CHANGE_FONT
if ((toggling == FALSE) && EmFont)
CloseFont(EmFont);/* access_count-- */
#endif
#ifdef DO_MENU
if (toggling == FALSE) {
ClearMenuStrip(EmW);
DisposeMenus(EmacsMenu);
}
#endif
CloseWindow(EmW);
case 3: /* couldn't open window */
#ifdef CHANGE_FONT
CloseLibrary(DiskfontBase);
#endif
case 21: /* couldn't open diskfonts */
CloseLibrary(IntuitionBase);
case 2: /* couldn't open Intuition */
CloseLibrary(GfxBase);
case 1: /* couldn't open graphics -- do nothing */
break;
}
return(0);
}